package cn.iocoder.yudao.module.scrm.util;

import cn.hutool.core.util.ObjUtil;
import cn.iocoder.yudao.module.scrm.dal.dataobject.business.BusinessDO;
import cn.iocoder.yudao.module.scrm.dal.dataobject.clue.ClueDO;
import cn.iocoder.yudao.module.scrm.dal.dataobject.invoice.InvoiceDO;
import cn.iocoder.yudao.module.scrm.dal.dataobject.order.OrderDO;
import cn.iocoder.yudao.module.scrm.dal.dataobject.receivable.ReceivableDO;
import cn.iocoder.yudao.module.scrm.dal.dataobject.refund.RefundDO;
import cn.iocoder.yudao.module.scrm.dal.mysql.business.ScrmBusinessMapper;
import cn.iocoder.yudao.module.scrm.dal.mysql.clue.ClueMapper;
import cn.iocoder.yudao.module.scrm.dal.mysql.invoice.InvoiceMapper;
import cn.iocoder.yudao.module.scrm.dal.mysql.order.OrderMapper;
import cn.iocoder.yudao.module.scrm.dal.mysql.receivable.ReceivableMapper;
import cn.iocoder.yudao.module.scrm.dal.mysql.refund.RefundMapper;
import cn.iocoder.yudao.module.scrm.enums.common.CrmBizTypeEnum;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;
import java.util.function.Function;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.scrm.enums.ErrorCodeConstants.ORDER_NOT_EXISTS;
import static cn.iocoder.yudao.module.scrm.enums.ErrorCodeConstants.SYSTEM_NUMBER_NOT_EXISTS;

/**
 * 生成唯一的系统编号
 * @Author LiZhiMin
 * @Date 2024/5/17 11:10
 */



@Component
public class CheckNoGeneratorUtil {

    @Resource
    private ClueMapper clueMapper; // 线索

    @Resource
    private ScrmBusinessMapper businessMapper; // 商机

    @Resource
    private OrderMapper orderMapper; // 商机

    @Resource
    private ReceivableMapper receivableMapper; // 回款

    @Resource
    private RefundMapper refundMapper; // 退款

    @Resource
    private InvoiceMapper invoiceMapper;// 发票


    //随机生成系统中不存在的系统编号
    public String generateUniqueCheckNo(Integer type) {
        String checkNo;
        do {
            checkNo = generateCheckNo(type);
        } while (isCheckNoUnique(checkNo,type));
        return checkNo;
    }

    //生成编号 xs+年月日+6位随机数
    private String generateCheckNo(Integer type) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
        String dateStr = dateFormat.format(new Date());

        Random random = new Random();
        int randomNumber = 100000 + random.nextInt(900000); // 生成6位随机数

        String prefixXs = "XS";
        String prefixSj = "SJ";
        String prefixDd = "DD";
        String prefixHk = "HK";
        String prefixTk = "TK";
        String prefixFp = "FP";
        if(ObjUtil.equal(CrmBizTypeEnum.CRM_CLUE.getType(),type)) { //线索
            return prefixXs + dateStr + randomNumber;
        }else  if (ObjUtil.equal(CrmBizTypeEnum.CRM_BUSINESS.getType(),type)) { //商机
            return prefixSj + dateStr + randomNumber;
        }else  if (ObjUtil.equal(CrmBizTypeEnum.CRM_ORDER.getType(),type)) { //订单
            return prefixDd + dateStr + randomNumber;
        }else  if (ObjUtil.equal(CrmBizTypeEnum.CRM_RECEIVABLE.getType(),type)) { //回款
            return prefixHk + dateStr + randomNumber;
        }else  if (ObjUtil.equal(CrmBizTypeEnum.CRM_REFUND.getType(),type)) { //退款
            return prefixTk + dateStr + randomNumber;
        }else  if (ObjUtil.equal(CrmBizTypeEnum.CRM_INVOICE.getType(),type)) { //发票
            return prefixFp + dateStr + randomNumber;
        }else{
            throw exception(SYSTEM_NUMBER_NOT_EXISTS);
        }

    }

    //校验编号在数据库中是否存在
    private boolean isCheckNoUniques(String systemNumber, Integer type) {

        if (ObjUtil.equal(CrmBizTypeEnum.CRM_CLUE.getType(),type)) { //线索
            QueryWrapper<ClueDO> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("system_number", systemNumber);
            int count = Math.toIntExact(clueMapper.selectCount(queryWrapper));
            return count != 0;
        }else  if (ObjUtil.equal(CrmBizTypeEnum.CRM_BUSINESS.getType(),type)) { //商机
            QueryWrapper<BusinessDO> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("system_number", systemNumber);
            int count = Math.toIntExact(businessMapper.selectCount(queryWrapper));
            return count != 0;
        }else  if (ObjUtil.equal(CrmBizTypeEnum.CRM_ORDER.getType(),type)) { //订单
            QueryWrapper<OrderDO> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("system_number", systemNumber);
            int count = Math.toIntExact(orderMapper.selectCount(queryWrapper));
            return count != 0;
        }else{
            throw exception(SYSTEM_NUMBER_NOT_EXISTS);
        }
    }

    private boolean isCheckNoUnique(String systemNumber, Integer type) {
        QueryWrapper<?> queryWrapper;
        Function<QueryWrapper<?>, Long> countFunction;
        if (ObjUtil.equal(CrmBizTypeEnum.CRM_CLUE.getType(),type)) { //线索
            queryWrapper = new QueryWrapper<ClueDO>().eq("system_number", systemNumber);
            countFunction = wrapper -> clueMapper.selectCount((Wrapper<ClueDO>) wrapper);
        }else  if (ObjUtil.equal(CrmBizTypeEnum.CRM_BUSINESS.getType(),type)) { //商机
            queryWrapper = new QueryWrapper<BusinessDO>().eq("system_number", systemNumber);
            countFunction = wrapper -> businessMapper.selectCount((Wrapper<BusinessDO>) wrapper);
        }else  if (ObjUtil.equal(CrmBizTypeEnum.CRM_ORDER.getType(),type)) { //订单
            queryWrapper = new QueryWrapper<OrderDO>().eq("system_number", systemNumber);
            countFunction = wrapper -> orderMapper.selectCount((Wrapper<OrderDO>) wrapper);
        }else  if (ObjUtil.equal(CrmBizTypeEnum.CRM_RECEIVABLE.getType(),type)) { //回款
            queryWrapper = new QueryWrapper<ReceivableDO>().eq("no", systemNumber);
            countFunction = wrapper -> receivableMapper.selectCount((Wrapper<ReceivableDO>) wrapper);
        } else  if (ObjUtil.equal(CrmBizTypeEnum.CRM_REFUND.getType(),type)) { //退款
            queryWrapper = new QueryWrapper<RefundDO>().eq("no", systemNumber);
            countFunction = wrapper -> refundMapper.selectCount((Wrapper<RefundDO>) wrapper);
        }else  if (ObjUtil.equal(CrmBizTypeEnum.CRM_RECEIVABLE.getType(),type)) { //发票
            queryWrapper = new QueryWrapper<InvoiceDO>().eq("no", systemNumber);
            countFunction = wrapper -> invoiceMapper.selectCount((Wrapper<InvoiceDO>) wrapper);
        }else {
            throw exception(SYSTEM_NUMBER_NOT_EXISTS);
        }
        return countFunction.apply(queryWrapper) != 0;
    }

}
